﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using QuickGet.Core.Stores;
using QuickGet.EntityFrameworkCore.Stores;

namespace QuickGet.EntityFrameworkCore
{
    public static class DatabaseConfigureExtensions
    {
        public static IServiceCollection AddDatabaseOptions(this IServiceCollection services)
        {
            services.AddTransient<IConfigureOptions<DatabaseOptions>>(sp =>
            {
                var config = sp.GetService<IConfiguration?>();
                return new ConfigureOptions<DatabaseOptions>(options => config?.Bind("Database", options));
            });

            return services;
        }

        public static void ConfigureDatabaseProvider(IServiceProvider serviceProvider, DbContextOptionsBuilder builder)
        {
            var config = serviceProvider.GetService<IConfiguration?>();
            var databaseOption = serviceProvider.GetService<IOptions<DatabaseOptions>>()?.Value;
            var connectionString = config?.GetConnectionString(databaseOption?.ConnectionName ?? "");

            switch (databaseOption?.Type)
            {
                case DatabaseTypes.Sqlite:
                    builder.UseSqlite(connectionString, op =>
                    {
                        op.MigrationsAssembly("QuickGet.EntityFrameworkCore.Sqlite");
                        op.MigrationsHistoryTable("__EFMigrationHistories");
                    });

                    break;
                case DatabaseTypes.Postgres:
                    builder.UseNpgsql(connectionString, op =>
                    {
                        op.MigrationsAssembly("QuickGet.EntityFrameworkCore.Npgsql");
                        op.MigrationsHistoryTable("__EFMigrationHistories");
                    });
                    
                    break;
                default:
                    throw new (databaseOption?.Type ?? "<NULL>");
            }
        }
    
        public static IServiceCollection AddEntityFrameworkCore<TDbContext>(
            this IServiceCollection services, 
            string connectionName = "Default") 
            where TDbContext : DbContext
        {
            services.AddDatabaseOptions();
            services.AddDbContext<TDbContext>(ConfigureDatabaseProvider);

            services.AddScoped<IPackageSourceStore, PackageSourceStore>();
            services.AddScoped<IPackageStore, PackageStore>();
        
            return services;
        }
    }
}
